home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 090 / cmln1086.arc / ASSEMBLY.LTG next >
Text File  |  1986-09-15  |  11KB  |  320 lines

  1. Assembly and High-Level Control Constructs by David Long
  2.  
  3. Listing 1
  4.  
  5. .xlist                          ;Listing off
  6. ;------------------------------------------
  7. ;Structured assembly language macro package
  8. ;
  9. ;For Microsoft/IBM macro assemblers
  10. ;
  11. ;Author: David Long
  12. ;Last edited: 07/08/86
  13. ;------------------------------------------
  14. ;
  15. ;-------------------
  16. ;Miscellaneous notes
  17. ;
  18. ;Only short jumps are generated for all constructs.  Separate stacks
  19. ;are used for each construct to facility adding constructs for abnormal
  20. ;termination (e.g., BREAK to exit a DO/WHILE/ENDWH loop).  Some notes
  21. ;on the assembler syntax: The & operator causes the macro parameter(s)
  22. ;immediately preceding/following it to be expanded (e.g., if FOO and BAR
  23. ;are parameters with values BAR and FOO respectively, FOO&BAR will expand
  24. ;as BARFOO).  The % operator causes evaluation of an expression (e.g.,
  25. ;if the label FOOBAR has the value 31, then calling a macro with the
  26. ;parameter %FOOBAR is the same as calling the macro with the parameter
  27. ;31 as a string, i.e., as the digits 3 and 1).
  28. ;-------------------
  29. ;
  30. ;-------------------
  31. ;Repeat/until macros
  32. ;Usage:
  33. ;_repeat        ;Beginning of loop
  34. ;   xxxxx       ;Body and test
  35. ;_until cc      ;Loop unless condition code cc holds
  36. ;-------------------
  37. ;
  38. ;_repeat generates the code for the start of a repeat statement.
  39. ;
  40. _repeat macro
  41. _push _rep,%_repcnt             ;;Save count on stack
  42. _label _rep,%_repcnt            ;;Generate label for top of loop
  43. _repcnt = _repcnt+01h
  44. endm
  45. ;
  46. ;_until generates the code for the end of a repeat statement.
  47. ;
  48. _until macro condition
  49. _pop _rep                       ;;Get count for last _rep in _num
  50. _mkijm condition,_rep,%_num     ;;Create jump with inverse condition code
  51. endm
  52. ;
  53. ;---------------
  54. ;Do/while macros
  55. ;Usage:
  56. ;_do            ;Beginning of testè;   xxxxx       ;Loop test
  57. ;_while cc      ;Exit if condition code cc does not hold
  58. ;   xxxxx       ;Body
  59. ;_endwh         ;End of body - loop to start of test
  60. ;---------------
  61. ;
  62. ;_do generates the code for the beginning of a while statement.
  63. ;
  64. _do macro
  65. _push _while,%_whilecnt         ;;Save count on stack
  66. _label _while,%_whilecnt        ;;Generate label for start of test
  67. _whilecnt = _whilecnt+01h
  68. endm
  69. ;
  70. ;_while generates the code for the middle part of a while statement.
  71. ;
  72. _while macro condition
  73. _pop _while                     ;;Get count for last _do in _num
  74. _push _while,%_num              ;;Resave
  75. _mkijm condition,_endwh,%_num   ;;Create jump with inverse condition code
  76. endm
  77. ;
  78. ;_endwh generates the code for the end of a while statement.
  79. ;
  80. _endwh macro
  81. _pop _while                     ;;Get count for last _do in _num
  82. _mkijm un,_while,%_num          ;;Create unconditional jump to test
  83. _label _endwh,%_num             ;;Generate label for end of construct
  84. endm
  85. ;
  86. ;-------------------
  87. ;If/else macros
  88. ;Usage:
  89. ;_if cc         ;Skip body if condition code cc does not hold
  90. ;   xxxxx       ;Body
  91. ;_endif         ;End of body
  92. ;or:
  93. ;_if cc         ;Skip to body of _else part if cc does not hold
  94. ;   xxxxx       ;Body of _if part
  95. ;_else          ;Skip to end of construct and mark start of _else part
  96. ;   xxxxx       ;Body of _else part
  97. ;_endif         ;End of construct
  98. ;-------------------
  99. ;
  100. ;_if generates the code for the beginning of an if statement.
  101. ;
  102. _if macro condition
  103. _push _else,%_elsecnt                   ;;Save count on stack
  104. _mkijm condition,_else,%_elsecnt        ;;Create jump with inverse condition
  105. _elsecnt = _elsecnt+01h
  106. endm
  107. ;
  108. ;_else generates the code for the middle of an if statement.
  109. ;
  110. _else macroè_pop _else                              ;;Get count for last _if in _num
  111. _push _else,%_num                       ;;Resave
  112. _mkijm un,_endif,%_num                  ;;Create unconditional jump to end
  113. _label _else,%_num                      ;;Mark start of _else part
  114. endm
  115. ;
  116. ;_endif generates the code for the end of an if statement.
  117. ;
  118. _endif macro
  119. _pop _else                              ;;Get count for last _if/_else
  120. if1                                     ;;If pass 1
  121.    _?def _else,%_num                    ;;   See if _elsexx is defined
  122.    if _defined                          ;;   If so
  123.       _label _endif,%_num               ;;      Label end of construct
  124.    else                                 ;;   If not
  125.       _label _else,%_num                ;;      Pretend the _else is here
  126.    endif
  127. endif
  128. endm
  129. ;
  130. ;---------------------------------------------
  131. ;Utility macros for pushing numbers on a stack
  132. ;Usage:
  133. ;_push stacknm,num      ;Push num on stack named stacknm
  134. ;---------------------------------------------
  135. ;
  136. ;_push and _put push a number on the appropriate stack.
  137. ;
  138. _push macro stacknm,num
  139. ;;Concatenate stacknm with '_ptr' to get the variable which has the top of
  140. ;;stack index (call the index n).  Call _put with the ASCII representation
  141. ;;of n together with stacknm and num.
  142. _put stacknm,%&stacknm&_ptr,num
  143. stacknm&_ptr = stacknm&_ptr+01h         ;;Increment stack pointer
  144. endm
  145. ;
  146. _put macro stacknm,pntr,num
  147. ;;Concatenate stacknm with '_st' and the ASCII representation of the
  148. ;;stack pointer to get a variable.  Assign num to that variable.
  149. stacknm&_st&pntr = num
  150. endm
  151. ;
  152. ;----------------------------------------------
  153. ;Utility macros for popping numbers off a stack
  154. ;Usage:
  155. ;_pop stacknm           ;Pop the stack named stacknm into the variable _num
  156. ;----------------------------------------------
  157. ;
  158. ;_pop and _fetch get a number off the appropriate stack.
  159. ;
  160. _pop macro stacknm
  161. ife stacknm&_ptr                                ;;If stack is empty
  162.    %out Structured statement nesting error
  163. else                                            ;;If stack is not empty
  164.    stacknm&_ptr = stacknm&_ptr-01h              ;;   Decrement stack pointerè   ;;Concatenate stacknm with '_ptr' to get the variable which holds the
  165.    ;;top of stack index (call the index n).  Call _fetch with the ASCII
  166.    ;;representation of n, together with stacknm.
  167.    _fetch stacknm,%&stacknm&_ptr
  168. endif
  169. endm
  170. ;
  171. _fetch macro stacknm,pntr
  172. ;;Concatenate stacknm with '_st' and the ASCII represenation of the stack
  173. ;;pointer to get a variable.  Set _num to the value of that variable.
  174. _num = stacknm&_st&pntr
  175. endm
  176. ;
  177. ;------------------------------------------------------------------
  178. ;Utility macros for creating jumps with the opposite of a condition
  179. ;Usage:
  180. ;_mkijm condition,base,number   ;Create jump with inverse of condition
  181.                                 ;to the label formed by concatenating
  182.                                 ;base with number
  183. ;------------------------------------------------------------------
  184. ;
  185. ;_mkijm and _mkjmp create a jump instruction with the inverse of a condition.
  186. ;
  187. _mkijm macro condition,base,number
  188. _mkjmp %_inv_&condition,base&number     ;;Call _mkjmp with opcode and dest 
  189. endm
  190. ;
  191. _mkjmp macro jmpopcode,dest
  192. jmp short dest                          ;;Create jump (compute displacement)
  193. org $-02h                               ;;Back up to jmp opcode
  194. db jmpopcode                            ;;Install correct opcode
  195. org $+01                                ;;Position back to end of jump
  196. endm
  197. ;
  198. ;----------------------------
  199. ;Miscellaneous utility macros
  200. ;Usage:
  201. ;_label base,number             ;Concatenate base and number to form label
  202. ;_?def base,number              ;Form label from base and number.  Set
  203. ;                               ;_defined to zero if the label is undefined
  204. ;                               ;or set _defined nonzero if it is defined.
  205. ;----------------------------
  206. ;
  207. ;_label forms a label.
  208. ;
  209. _label macro base,number
  210. base&number label near
  211. endm
  212. ;
  213. ;_?def checks to see if a label is defined.
  214. ;
  215. _?def macro base,number
  216. ifdef base&number
  217.    _defined = 0ffh
  218. elseè   _defined = 00h
  219. endif
  220. endm
  221. ;
  222. ;---------
  223. ;Variables
  224. ;---------
  225. ;
  226. _inv_a      = 076h              ;Jump opcodes - jna = 076h
  227. _inv_ae     = 072h              ;jnae = 072h
  228. _inv_b      = 073h              ;jnb = 073h
  229. _inv_be     = 077h              ;jnbe = 077h
  230. _inv_c      = 073h              ;jnc = 073h
  231. _inv_e      = 075h              ;jne = 075h
  232. _inv_g      = 07eh              ;jng = 07eh
  233. _inv_ge     = 07ch              ;   ...
  234. _inv_l      = 07dh
  235. _inv_le     = 07fh
  236. _inv_na     = 077h
  237. _inv_nae    = 073h
  238. _inv_nb     = 072h
  239. _inv_nbe    = 076h
  240. _inv_nc     = 072h
  241. _inv_ne     = 074h
  242. _inv_ng     = 07fh
  243. _inv_nge    = 07dh
  244. _inv_nl     = 07ch
  245. _inv_nle    = 07eh
  246. _inv_no     = 070h
  247. _inv_np     = 07ah
  248. _inv_ns     = 078h
  249. _inv_nz     = 074h
  250. _inv_o      = 071h
  251. _inv_p      = 07bh
  252. _inv_pe     = 07bh
  253. _inv_po     = 07ah
  254. _inv_s      = 079h
  255. _inv_z      = 075h
  256. _inv_un     = 0ebh              ;Do not invert unconditional (jmp short)
  257. _repcnt     = 00h               ;Number of last _rep
  258. _elsecnt    = 00h               ;Number of last _if
  259. _whilecnt   = 00h               ;Number of last _do
  260. _rep_ptr    = 00h               ;Stack pointer for _rep stack
  261. _else_ptr   = 00h               ;Stack pointer for _if stack
  262. _while_ptr  = 00h               ;Stack pointer for _do stack
  263. _num        = 00h               ;Number last popped off a stack
  264. _defined    = 00h               ;Set by _?def (q.v.)
  265. .xcref _num,_defined,_repcnt    ;Do not cross reference
  266. .xcref _elsecnt,_whilecnt
  267. .xcref _rep_ptr,_else_ptr
  268. .xcref _while_ptr
  269. .xcref _inv_a,_inv_ae,_inv_b,_inv_be
  270. .xcref _inv_c,_inv_e,_inv_g,_inv_ge
  271. .xcref _inv_l,_inv_le,_inv_na,_inv_nae
  272. .xcref _inv_nb,_inv_nbe,_inv_nc,_inv_ne
  273. .xcref _inv_ng,_inv_nge,_inv_nl,_inv_nle
  274. .xcref _inv_no,_inv_np,_inv_ns,_inv_nz
  275. .xcref _inv_o,_inv_p,_inv_pe,_inv_po
  276. .xcref _inv_s,_inv_z,_inv_un
  277. .list                           ;Listing back on
  278.  
  279.  
  280. Listing 2
  281.  
  282.                 ...
  283. tab equ 09h                     ;ASCII horizontal tab character
  284.                 ...
  285. include STRUCT.ASM              ;Include control structure macrosè                ...
  286. ;
  287. ;---------------------
  288. ;Procedure expand_tabs
  289. ;
  290. ;Expand tabs to spaces in string (assumes tabs every eight columns).
  291. ;
  292. ;Entry:
  293. ;  Pointer to string (00h terminated) in ds:si
  294. ;  Pointer to destination buffer in es:di
  295. ;  Direction flag clear
  296. ;Exit:
  297. ;  Ax, si, di altered
  298. ;---------------------
  299. ;
  300. expand_tabs proc near
  301. _do
  302.    lodsb                        ;Get character in al
  303.    test al,al
  304. _while ne                       ;While not end of string
  305.    cmp al,tab
  306.    _if e                        ;If tab character
  307.       mov al,' '                ;Will pad with spaces
  308.       _repeat
  309.          stosb                  ;Pad
  310.          test di,000000111b
  311.       _until z                  ;Repeat until eight character boundary
  312.    _else                        ;If not tab
  313.       stosb                     ;Save character
  314.    _endif
  315. _endwh
  316. stosb                           ;Move 00h terminator
  317. ret
  318. expand_tabs endp
  319.                 ...
  320.